<template>
	<el-radio-group ref="radioGroupRef" :disabled="_disabled" :size="_size" v-bind="$attrs" @change="modelValueChanged">
		<el-radio v-for="item in options" v-if="_cancelAble" :key="item.value" :ref="radioRefs.set" :border="_border" :disabled="item.disabled"
		          :value="item.value" @click.prevent="radioClick(item)">
			{{ item.label }}
		</el-radio>
		<el-radio v-for="item in options" v-else :key="item.value" :border="_border" :disabled="item.disabled" :value="item.value">
			{{ item.label }}
		</el-radio>
	</el-radio-group>
</template>

<script lang="ts" setup>

import {computed, ref} from 'vue'
import type {RadioGroupInstance, RadioInstance} from 'element-plus'
import {useTemplateRefsList} from '@vueuse/core'
import {getBusinessCodeData} from '@/utils/commonUtil'

interface Props {
	codeType: string
	hideValue?: boolean
	disabled?: boolean
	disabledValueArray?: BusinessCodeTreeNode['value'][]
	hideValueArray?: BusinessCodeTreeNode['value'][]
	border?: boolean
	cancelAble?: boolean
	size?: 'large' | 'default' | 'small'
	forceStringValue?: boolean
}

interface OptionItem {
	label: string
	value: BusinessCodeRadioValue
	disabled: boolean
}

const props = withDefaults(defineProps<Props>(), {
	hideValue: true,
	disabled: false,
	disabledValueArray: () => [],
	hideValueArray: () => [],
	border: false,
	cancelAble: true,
	forceStringValue: false,
	size: 'default'
})

const emits = defineEmits<{
	(e: 'update:modelValue', value?: BusinessCodeRadioValue): void
	(e: 'change', value?: BusinessCodeRadioValue): void
}>()

const radioRefs = useTemplateRefsList<RadioInstance>()

const _disabled = computed(() => props.disabled)
const _size = computed(() => props.size)
const _cancelAble = computed(() => props.cancelAble)
const _border = computed(() => props.border)

const radioGroupRef = ref<RadioGroupInstance>()

const options = computed<OptionItem[]>(() => {
	const options = []
	const businessCodeData = getBusinessCodeData(props.codeType)
	if (businessCodeData && businessCodeData.length > 0) {
		for (const businessCode of businessCodeData) {
			if (props.hideValueArray.includes(businessCode.value)) {
				continue
			}
			options.push({
				label: props.hideValue ? businessCode.label : `${businessCode.value} : ${businessCode.label}`,
				value: handleValue(businessCode.value),
				disabled: props.disabledValueArray.includes(businessCode.value)
			})
		}
	}
	return options
})

const radioClick = (option: OptionItem) => {
	// 禁用时不可点击
	if (radioRefs.value[options.value.indexOf(option)].$el.classList.contains('is-disabled')) {
		return
	}
	// if (_disabled.value || option.disabled) {
	// 	return
	// }
	const modelValue = radioGroupRef.value!.modelValue === option.value ? undefined : option.value
	emits('update:modelValue', modelValue)
	emits('change', modelValue)
}

const handleValue = (value: string): BusinessCodeRadioValue => {
	if (props.forceStringValue) {
		return value
	}
	// 尝试转换为boolean
	if (value === 'true' || value === 'false') {
		return JSON.parse(value)
	}
	// 尝试转换为number
	const numberValue = Number(value)
	if (Number.isSafeInteger(numberValue)) {
		return numberValue
	}
	// 其他情况使用string
	else {
		return value
	}
}

/**
 * 向父组件传值
 */
const modelValueChanged = (value: BusinessCodeRadioValue) => {
	emits('update:modelValue', value)
	emits('change', value)
}

</script>

<style lang="scss" scoped>

</style>
